home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '87 / Source ƒ.sea / Source ƒ / emacs source ƒ / BASIC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-28  |  11.5 KB  |  384 lines  |  [TEXT/MARC]

  1. /*
  2.  * The routines in this file move the cursor around on the screen. They
  3.  * compute a new value for the cursor, then adjust ".". The display code
  4.  * always updates the cursor location, so only moves between lines, or
  5.  * functions that adjust the top line in the window and invalidate the
  6.  * framing, are hard.
  7.  */
  8. #include        <stdio.h>
  9. #include    "estruct.h"
  10. #include        "edef.h"
  11.  
  12. /*
  13.  * Move the cursor to the
  14.  * beginning of the current line.
  15.  * Trivial.
  16.  */
  17. gotobol(f, n)
  18. {
  19.         curwp->w_doto  = 0;
  20.         return (TRUE);
  21. }
  22.  
  23. /*
  24.  * Move the cursor backwards by "n" characters. If "n" is less than zero call
  25.  * "forwchar" to actually do the move. Otherwise compute the new cursor
  26.  * location. Error if you try and move out of the buffer. Set the flag if the
  27.  * line pointer for dot changes.
  28.  */
  29. backchar(f, n)
  30. register int    n;
  31. {
  32.         register LINE   *lp;
  33.  
  34.         if (n < 0)
  35.                 return (forwchar(f, -n));
  36.         while (n--) {
  37.                 if (curwp->w_doto == 0) {
  38.                         if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
  39.                                 return (FALSE);
  40.                         curwp->w_dotp  = lp;
  41.                         curwp->w_doto  = llength(lp);
  42.                         curwp->w_flag |= WFMOVE;
  43.                 } else
  44.                         curwp->w_doto--;
  45.         }
  46.         return (TRUE);
  47. }
  48.  
  49. /*
  50.  * Move the cursor to the end of the current line. Trivial. No errors.
  51.  */
  52. gotoeol(f, n)
  53. {
  54.         curwp->w_doto  = llength(curwp->w_dotp);
  55.         return (TRUE);
  56. }
  57.  
  58. /*
  59.  * Move the cursor forwwards by "n" characters. If "n" is less than zero call
  60.  * "backchar" to actually do the move. Otherwise compute the new cursor
  61.  * location, and move ".". Error if you try and move off the end of the
  62.  * buffer. Set the flag if the line pointer for dot changes.
  63.  */
  64. forwchar(f, n)
  65. register int    n;
  66. {
  67.         if (n < 0)
  68.                 return (backchar(f, -n));
  69.         while (n--) {
  70.                 if (curwp->w_doto == llength(curwp->w_dotp)) {
  71.                         if (curwp->w_dotp == curbp->b_linep)
  72.                                 return (FALSE);
  73.                         curwp->w_dotp  = lforw(curwp->w_dotp);
  74.                         curwp->w_doto  = 0;
  75.                         curwp->w_flag |= WFMOVE;
  76.                 } else
  77.                         curwp->w_doto++;
  78.         }
  79.         return (TRUE);
  80. }
  81.  
  82. gotoline(f, n)        /* move to a particular line.
  83.                argument (n) must be a positive integer for
  84.                this to actually do anything        */
  85.  
  86. {
  87.     if (n < 1)        /* if a bogus argument...then leave */
  88.         return(FALSE);
  89.  
  90.     /* first, we go to the start of the buffer */
  91.         curwp->w_dotp  = lforw(curbp->b_linep);
  92.         curwp->w_doto  = 0;
  93.     return(forwline(f, n-1));
  94. }
  95.  
  96. /*
  97.  * Goto the beginning of the buffer. Massive adjustment of dot. This is
  98.  * considered to be hard motion; it really isn't if the original value of dot
  99.  * is the same as the new value of dot. Normally bound to "M-<".
  100.  */
  101. gotobob(f, n)
  102. {
  103.         curwp->w_dotp  = lforw(curbp->b_linep);
  104.         curwp->w_doto  = 0;
  105.         curwp->w_flag |= WFHARD;
  106.         return (TRUE);
  107. }
  108.  
  109. /*
  110.  * Move to the end of the buffer. Dot is always put at the end of the file
  111.  * (ZJ). The standard screen code does most of the hard parts of update.
  112.  * Bound to "M->".
  113.  */
  114. gotoeob(f, n)
  115. {
  116.         curwp->w_dotp  = curbp->b_linep;
  117.         curwp->w_doto  = 0;
  118.         curwp->w_flag |= WFHARD;
  119.         return (TRUE);
  120. }
  121.  
  122. /*
  123.  * Move forward by full lines. If the number of lines to move is less than
  124.  * zero, call the backward line function to actually do it. The last command
  125.  * controls how the goal column is set. Bound to "C-N". No errors are
  126.  * possible.
  127.  */
  128. forwline(f, n)
  129. {
  130.         register LINE   *dlp;
  131.  
  132.         if (n < 0)
  133.                 return (backline(f, -n));
  134.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
  135.                 curgoal = getccol(FALSE);       /* not C-P or C-N       */
  136.         thisflag |= CFCPCN;
  137.         dlp = curwp->w_dotp;
  138.         while (n-- && dlp!=curbp->b_linep)
  139.                 dlp = lforw(dlp);
  140.         curwp->w_dotp  = dlp;
  141.         curwp->w_doto  = getgoal(dlp);
  142.         curwp->w_flag |= WFMOVE;
  143.         return (TRUE);
  144. }
  145.  
  146. /*
  147.  * This function is like "forwline", but goes backwards. The scheme is exactly
  148.  * the same. Check for arguments that are less than zero and call your
  149.  * alternate. Figure out the new line and call "movedot" to perform the
  150.  * motion. No errors are possible. Bound to "C-P".
  151.  */
  152. backline(f, n)
  153. {
  154.         register LINE   *dlp;
  155.  
  156.         if (n < 0)
  157.                 return (forwline(f, -n));
  158.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
  159.                 curgoal = getccol(FALSE);       /* last isn't C-P, C-N  */
  160.         thisflag |= CFCPCN;
  161.         dlp = curwp->w_dotp;
  162.         while (n-- && lback(dlp)!=curbp->b_linep)
  163.                 dlp = lback(dlp);
  164.         curwp->w_dotp  = dlp;
  165.         curwp->w_doto  = getgoal(dlp);
  166.         curwp->w_flag |= WFMOVE;
  167.         return (TRUE);
  168. }
  169.  
  170. #if    WORDPRO
  171. gotobop(f, n)    /* go back to the beginning of the current paragraph
  172.            here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  173.            combination to delimit the beginning of a paragraph    */
  174.  
  175. int f, n;    /* default Flag & Numeric argument */
  176.  
  177. {
  178.     register int suc;    /* success of last backchar */
  179.  
  180.     if (n < 0)    /* the other way...*/
  181.         return(gotoeop(f, -n));
  182.  
  183.     while (n-- > 0) {    /* for each one asked for */
  184.  
  185.         /* first scan back until we are in a word */
  186.         suc = backchar(FALSE, 1);
  187.         while (!inword() && suc)
  188.             suc = backchar(FALSE, 1);
  189.         curwp->w_doto = 0;    /* and go to the B-O-Line */
  190.  
  191.         /* and scan back until we hit a <NL><NL> or <NL><TAB>
  192.            or a <NL><SPACE>                    */
  193.         while (lback(curwp->w_dotp) != curbp->b_linep)
  194.             if (llength(curwp->w_dotp) != 0 &&
  195.                 lgetc(curwp->w_dotp, curwp->w_doto) != TAB &&
  196.                 lgetc(curwp->w_dotp, curwp->w_doto) != ' ')
  197.                 curwp->w_dotp = lback(curwp->w_dotp);
  198.             else
  199.                 break;
  200.  
  201.         /* and then forward until we are in a word */
  202.         suc = forwchar(FALSE, 1);
  203.         while (suc && !inword())
  204.             suc = forwchar(FALSE, 1);
  205.     }
  206.     curwp->w_flag |= WFMOVE;    /* force screen update */
  207.     return(TRUE);
  208. }
  209.  
  210. gotoeop(f, n)    /* go forword to the end of the current paragraph
  211.            here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  212.            combination to delimit the beginning of a paragraph    */
  213.  
  214. int f, n;    /* default Flag & Numeric argument */
  215.  
  216. {
  217.     register int suc;    /* success of last backchar */
  218.  
  219.     if (n < 0)    /* the other way...*/
  220.         return(gotobop(f, -n));
  221.  
  222.     while (n-- > 0) {    /* for each one asked for */
  223.  
  224.         /* first scan forward until we are in a word */
  225.         suc = forwchar(FALSE, 1);
  226.         while (!inword() && suc)
  227.             suc = forwchar(FALSE, 1);
  228.         curwp->w_doto = 0;    /* and go to the B-O-Line */
  229.         if (suc)    /* of next line if not at EOF */
  230.             curwp->w_dotp = lforw(curwp->w_dotp);
  231.  
  232.         /* and scan forword until we hit a <NL><NL> or <NL><TAB>
  233.            or a <NL><SPACE>                    */
  234.         while (curwp->w_dotp != curbp->b_linep) {
  235.             if (llength(curwp->w_dotp) != 0 &&
  236.                 lgetc(curwp->w_dotp, curwp->w_doto) != TAB &&
  237.                 lgetc(curwp->w_dotp, curwp->w_doto) != ' ')
  238.                 curwp->w_dotp = lforw(curwp->w_dotp);
  239.             else
  240.                 break;
  241.         }
  242.  
  243.         /* and then backward until we are in a word */
  244.         suc = backchar(FALSE, 1);
  245.         while (suc && !inword()) {
  246.             suc = backchar(FALSE, 1);
  247.         }
  248.         curwp->w_doto = llength(curwp->w_dotp);    /* and to the EOL */
  249.     }
  250.     curwp->w_flag |= WFMOVE;    /* force screen update */
  251.     return(TRUE);
  252. }
  253. #endif
  254.  
  255. /*
  256.  * This routine, given a pointer to a LINE, and the current cursor goal
  257.  * column, return the best choice for the offset. The offset is returned.
  258.  * Used by "C-N" and "C-P".
  259.  */
  260. getgoal(dlp)
  261. register LINE   *dlp;
  262. {
  263.         register int    c;
  264.         register int    col;
  265.         register int    newcol;
  266.         register int    dbo;
  267.  
  268.         col = 0;
  269.         dbo = 0;
  270.         while (dbo != llength(dlp)) {
  271.                 c = lgetc(dlp, dbo);
  272.                 newcol = col;
  273.                 if (c == '\t')
  274.                         newcol |= 0x07;
  275.                 else if (c<0x20 || c==0x7F)
  276.                         ++newcol;
  277.                 ++newcol;
  278.                 if (newcol > curgoal)
  279.                         break;
  280.                 col = newcol;
  281.                 ++dbo;
  282.         }
  283.         return (dbo);
  284. }
  285.  
  286. /*
  287.  * Scroll forward by a specified number of lines, or by a full page if no
  288.  * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
  289.  * the overlap; this value is the default overlap value in ITS EMACS. Because
  290.  * this zaps the top line in the display window, we have to do a hard update.
  291.  */
  292. forwpage(f, n)
  293. register int    n;
  294. {
  295.         register LINE   *lp;
  296.  
  297.         if (f == FALSE) {
  298.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  299.                 if (n <= 0)                     /* Forget the overlap   */
  300.                         n = 1;                  /* if tiny window.      */
  301.         } else if (n < 0)
  302.                 return (backpage(f, -n));
  303. #if     CVMVAS
  304.         else                                    /* Convert from pages   */
  305.                 n *= curwp->w_ntrows;           /* to lines.            */
  306. #endif
  307.         lp = curwp->w_linep;
  308.         while (n-- && lp!=curbp->b_linep)
  309.                 lp = lforw(lp);
  310.         curwp->w_linep = lp;
  311.         curwp->w_dotp  = lp;
  312.         curwp->w_doto  = 0;
  313.         curwp->w_flag |= WFHARD;
  314.         return (TRUE);
  315. }
  316.  
  317. /*
  318.  * This command is like "forwpage", but it goes backwards. The "2", like
  319.  * above, is the overlap between the two windows. The value is from the ITS
  320.  * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
  321.  * reason.
  322.  */
  323. backpage(f, n)
  324. register int    n;
  325. {
  326.         register LINE   *lp;
  327.  
  328.         if (f == FALSE) {
  329.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  330.                 if (n <= 0)                     /* Don't blow up if the */
  331.                         n = 1;                  /* window is tiny.      */
  332.         } else if (n < 0)
  333.                 return (forwpage(f, -n));
  334. #if     CVMVAS
  335.         else                                    /* Convert from pages   */
  336.                 n *= curwp->w_ntrows;           /* to lines.            */
  337. #endif
  338.         lp = curwp->w_linep;
  339.         while (n-- && lback(lp)!=curbp->b_linep)
  340.                 lp = lback(lp);
  341.         curwp->w_linep = lp;
  342.         curwp->w_dotp  = lp;
  343.         curwp->w_doto  = 0;
  344.         curwp->w_flag |= WFHARD;
  345.         return (TRUE);
  346. }
  347.  
  348. /*
  349.  * Set the mark in the current window to the value of "." in the window. No
  350.  * errors are possible. Bound to "M-.".
  351.  */
  352. setmark(f, n)
  353. {
  354.         curwp->w_markp = curwp->w_dotp;
  355.         curwp->w_marko = curwp->w_doto;
  356.         mlwrite("[Mark set]");
  357.         return (TRUE);
  358. }
  359.  
  360. /*
  361.  * Swap the values of "." and "mark" in the current window. This is pretty
  362.  * easy, bacause all of the hard work gets done by the standard routine
  363.  * that moves the mark about. The only possible error is "no mark". Bound to
  364.  * "C-X C-X".
  365.  */
  366. swapmark(f, n)
  367. {
  368.         register LINE   *odotp;
  369.         register int    odoto;
  370.  
  371.         if (curwp->w_markp == NULL) {
  372.                 mlwrite("No mark in this window");
  373.                 return (FALSE);
  374.         }
  375.         odotp = curwp->w_dotp;
  376.         odoto = curwp->w_doto;
  377.         curwp->w_dotp  = curwp->w_markp;
  378.         curwp->w_doto  = curwp->w_marko;
  379.         curwp->w_markp = odotp;
  380.         curwp->w_marko = odoto;
  381.         curwp->w_flag |= WFMOVE;
  382.         return (TRUE);
  383. }
  384.